import axios from 'axios';
import type { ExchangeBody, ExchangeResponse, ApiConfig } from '../types';

// API服务类
export class ApiService {
  // 直接使用完整的API路径
  private static readonly EXCHANGE_DETAIL_URL = 'https://api.csqaq.com/api/v1/info/exchange_detail';
  // 备用API路径（使用代理，确保路径重写后正确）
  private static readonly EXCHANGE_DETAIL_URL_PROXY = '/api-proxy/api/v1/info/exchange_detail';
  // 备选方案3：使用直接代理路径
  private static readonly EXCHANGE_DETAIL_URL_DIRECT_PROXY = '/api/v1/info/exchange_detail';
  
  // 请求频率限制
  private static lastRequestTime: number = 0;
  private static readonly REQUEST_INTERVAL: number = 1000; // 1秒限制

  // 节流控制，确保1秒内只发送一次请求
  private static async throttle(): Promise<void> {
    const now: number = Date.now();
    const timeSinceLastRequest: number = now - ApiService.lastRequestTime;
    
    if (timeSinceLastRequest < ApiService.REQUEST_INTERVAL) {
      await new Promise<void>((resolve) => {
        setTimeout(resolve, ApiService.REQUEST_INTERVAL - timeSinceLastRequest);
      });
    }
    
    ApiService.lastRequestTime = Date.now();
  }

  // 获取挂刀行情详情数据
  static async fetchExchangeDetail(apiConfig: ApiConfig, exchangeBody: ExchangeBody): Promise<ExchangeResponse> {
    try {
      // 应用节流控制
      await ApiService.throttle();

      console.log('使用API Token:', apiConfig.apiToken);
      
      // 验证必要的请求参数
      if (!exchangeBody || !apiConfig.apiToken) {
        throw new Error('API请求错误: 缺少必要的请求参数');
      }
      
      // 验证必要字段 - 严格按照API文档要求
      if (!exchangeBody.page_index || exchangeBody.page_index < 1) {
        throw new Error('page_index必须是大于等于1的整数');
      }
      if (exchangeBody.res === undefined || ![0, 1].includes(exchangeBody.res)) {
        throw new Error('res必须是0或1');
      }
      if (!exchangeBody.platforms || !['BUFF-YYYP', 'BUFF', 'YYYP'].includes(exchangeBody.platforms)) {
        throw new Error('platforms必须是BUFF-YYYP、BUFF或YYYP之一');
      }
      if (exchangeBody.sort_by === undefined || ![0, 1].includes(exchangeBody.sort_by)) {
        throw new Error('sort_by必须是0或1');
      }

      // 构建请求体 - 只包含有效字段
      const validatedBody: Record<string, unknown> = {
        page_index: exchangeBody.page_index,
        res: exchangeBody.res,
        platforms: exchangeBody.platforms,
        sort_by: exchangeBody.sort_by
      };

      // 添加可选字段（如果存在且有效）
      if (exchangeBody.min_price !== undefined && exchangeBody.min_price >= 0) {
        validatedBody.min_price = exchangeBody.min_price;
      }
      if (exchangeBody.max_price !== undefined && exchangeBody.max_price > 0) {
        validatedBody.max_price = exchangeBody.max_price;
      }
      if (exchangeBody.text && exchangeBody.text.trim()) {
        validatedBody.text = exchangeBody.text.trim();
      }
      if (exchangeBody.turnover !== undefined && exchangeBody.turnover >= 0) {
        validatedBody.turnover = exchangeBody.turnover;
      }
      if (exchangeBody.buy !== undefined && [0, 1].includes(exchangeBody.buy)) {
        validatedBody.buy = exchangeBody.buy;
      }
      
      console.log('完整请求参数:', JSON.stringify(validatedBody));
      console.log('API Token:', apiConfig.apiToken);
      
      // 准备请求配置 - 严格按照API文档要求
      const requestConfig = {
        headers: {
          'ApiToken': apiConfig.apiToken, // 按照API文档要求使用ApiToken
          'Content-Type': 'application/json',
          'Accept': 'application/json',
          'User-Agent': 'SteamV5/1.0'
        },
        timeout: 20000, // 20秒超时
        withCredentials: false, // API文档未要求携带凭证
        validateStatus: (status: number) => status >= 200 && status < 300
      };
      
      console.log('请求配置:', {
        timeout: requestConfig.timeout,
        withCredentials: requestConfig.withCredentials,
        headers: {
          'ApiToken': apiConfig.apiToken ? '已设置' : '未设置',
          'Content-Type': requestConfig.headers['Content-Type'],
          'Accept': requestConfig.headers['Accept']
        }
      });
      
      // 尝试请求，使用三种方案依次尝试
      let response;
      let attemptCount = 0;
      const maxAttempts = 3;
      const urls = [
        ApiService.EXCHANGE_DETAIL_URL,
        ApiService.EXCHANGE_DETAIL_URL_PROXY,
        ApiService.EXCHANGE_DETAIL_URL_DIRECT_PROXY
      ];
      
      while (attemptCount < maxAttempts) {
        try {
          const url = urls[attemptCount];
          console.log(`尝试请求 ${url} (${attemptCount + 1}/${maxAttempts})`);
          
          // 添加请求开始时间记录
          const startTime = Date.now();
          response = await axios.post(url, validatedBody, requestConfig);
          const endTime = Date.now();
          
          console.log(`API响应成功 (${url})，状态码: ${response.status}，响应时间: ${endTime - startTime}ms`);
          break;
        } catch (attemptError) {
          attemptCount++;
          if (attemptCount >= maxAttempts) {
            throw attemptError;
          }
          console.warn(`尝试 ${attemptCount} 失败，错误: ${(attemptError as Error).message}，尝试替代地址`);
          // 重试前短暂延迟，避免立即重试导致的问题
          await new Promise(resolve => setTimeout(resolve, 500));
        }
      }
      
      if (!response) {
        throw new Error('所有API请求尝试均失败');
      }
      
      return response.data;
    } catch (error) {
      // 增强的错误处理
      if (axios.isAxiosError(error)) {
        if (error.response) {
          const status: number = error.response.status;
          const errorMsg: string = error.response.data?.msg || '';
          
          // 错误状态码映射 - 严格按照API文档中的状态码说明
          const errorMessages: Record<number, string> = {
            400: `用户不存在或Token验证未通过 (${errorMsg})`,
            401: `Token验证未通过，请检查API Token (${errorMsg})`,
            404: '接口错误统一返回',
            422: `请求数据格式错误 (${errorMsg || '请检查请求参数是否正确'})`,
            429: '客户端短时间内请求过多',
            500: `服务错误统一返回 (${errorMsg || '回传request_id可协助排查'})`,
            503: '网关异常或请求频繁'
          };
          
          const message = errorMessages[status] || `请求失败 (状态码: ${status}, 错误信息: ${errorMsg})`;
          console.error('API请求错误:', message);
          throw new Error(message);
        } else if (error.request) {
          // 详细的网络错误诊断信息
          console.error('网络错误类型:', error.code);
          console.error('网络错误详情:', error.message);
          console.error('请求URL:', error.config?.url);
          console.error('请求超时时间:', error.config?.timeout, 'ms');
          console.error('请求方法:', error.config?.method);
          console.error('请求头概览:', {
            'ApiToken': error.config?.headers?.['ApiToken'] ? '已设置' : '未设置',
            'Content-Type': error.config?.headers?.['Content-Type']
          });
          
          // 根据不同错误类型提供更具体的错误信息
          let specificErrorMsg = '';
          if (error.code === 'ECONNABORTED') {
            specificErrorMsg = '请求超时，请检查网络连接稳定性或API服务器响应速度';
          } else if (error.code === 'ENOTFOUND' || error.code === 'ERR_NAME_NOT_RESOLVED') {
            specificErrorMsg = '无法解析API服务器域名，请检查网络连接和DNS设置';
          } else if (error.code === 'ECONNREFUSED') {
            specificErrorMsg = '连接被拒绝，请检查API服务器是否在线';
          } else if (error.code === 'ERR_CERT_COMMON_NAME_INVALID' || error.code === 'ERR_BAD_SSL_CLIENT_AUTH_CERT') {
            specificErrorMsg = 'SSL证书验证失败，请检查证书配置';
          }
          
          throw new Error(`网络错误: ${error.message}。${specificErrorMsg}，请检查网络连接、防火墙设置或代理配置。`);
        } else {
          console.error('请求配置错误:', error);
          throw new Error('请求配置错误: ' + error.message);
        }
      }
      
      console.error('未知错误:', error);
      throw new Error('获取数据失败，请稍后重试: ' + (error as Error).message);
    }
  }

  // 计算收益率辅助方法
  static calculateProfitRate(buyPrice: number, sellPrice: number): number {
    if (buyPrice === 0) {
      return 0;
    }
    return ((sellPrice - buyPrice) / buyPrice) * 100;
  }
}